<html>
<head><meta charset="utf-8"><title>Support builtin macros · t-compiler/rust-analyzer · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/index.html">t-compiler/rust-analyzer</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html">Support builtin macros</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="179901934"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/179901934" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edwin Cheng <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#179901934">(Nov 05 2019 at 04:56)</a>:</h4>
<p>I am starting to work on adding builtin macros. (e.g: <code>concat!</code>) . My initial thought is to create each custom <code>MacroDef</code> for each builtin macros and registers these in the beginning of module collecting phase. Basically changing MacroDef as following:</p>
<div class="codehilite"><pre><span></span><span class="cp">#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]</span><span class="w"></span>
<span class="k">pub</span><span class="w"> </span><span class="k">enum</span> <span class="nc">MacroDefId</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">MacroDefSource</span><span class="p">(</span><span class="n">MacroDefSource</span><span class="p">),</span><span class="w"></span>
<span class="w">    </span><span class="n">MacroDefBuiltin</span><span class="p">(...)</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="c1">// `MacroDefSource` is the normal MacroDef</span>
<span class="cp">#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]</span><span class="w"></span>
<span class="k">pub</span><span class="w"> </span><span class="k">struct</span> <span class="nc">MacroDefSource</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">krate</span>: <span class="nc">CrateId</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">ast_id</span>: <span class="nc">AstId</span><span class="o">&lt;</span><span class="n">ast</span>::<span class="n">MacroCall</span><span class="o">&gt;</span><span class="p">,</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>


<p>Another option is to add a new type <code>ModuleDef::BultinMacro</code> and handle it separately (Although I hadn't figured out the whole path for how to do it)</p>
<p>Do anyone have any idea?</p>



<a name="179946332"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/179946332" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edwin Cheng <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#179946332">(Nov 05 2019 at 16:04)</a>:</h4>
<p><span class="user-mention" data-user-id="133169">@matklad</span> After studying how rustc implement <code>concat!</code> macro, I finally understand what you mean "include! and concat! seem to use "eager expansion" of some sorts.". </p>
<p>For example: </p>
<div class="codehilite"><pre><span></span><span class="n">macro_rules</span><span class="o">!</span><span class="w"> </span><span class="n">foo</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="p">()</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{</span><span class="n">a</span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;{}&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">concat</span><span class="o">!</span><span class="p">(</span><span class="n">foo</span><span class="o">!</span><span class="p">(),</span><span class="w"> </span><span class="n">bar</span><span class="o">!</span><span class="p">()));</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>


<p>When we try to expand <code>concat!</code>, we have to expand <code>foo!()</code> and <code>bar!()</code> first. And this order is different from what normal mbe is handled.</p>



<a name="180016506"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/180016506" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#180016506">(Nov 06 2019 at 09:53)</a>:</h4>
<p><span class="user-mention" data-user-id="216201">@Edwin Cheng</span> yeah, I think we need to extend <code>MacroDefId</code>. I imagine, in the end it might want to look like</p>
<div class="codehilite"><pre><span></span><span class="k">enum</span> <span class="nc">MacroDefId</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="n">DeclarativeMacro</span><span class="p">(</span><span class="n">DeclarativeMacro</span><span class="p">),</span><span class="w"></span>
<span class="w">  </span><span class="n">ProcMacro</span><span class="p">(</span><span class="n">ProcMacro</span><span class="p">),</span><span class="w"></span>
<span class="w">  </span><span class="n">BuiltinMacro</span><span class="p">(</span><span class="n">BuiltinMacro</span><span class="p">),</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>


<p>I think it makes sense to just hard-code bulitin macrod right now for simplicity (so, don't add them to <code>ModuleDef</code>), but, long term, I think nameres should be aware of such macros.</p>



<a name="180016607"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/180016607" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#180016607">(Nov 06 2019 at 09:55)</a>:</h4>
<p>And yeah, the hardest part about build-in macros is that they are not necessary restricted to <code>tt -&gt; tt</code> interface, and might do all sorts of weird call-backs into the compiler. I <em>hope</em> we can handle them clearly withing <code>hir_expand</code> framework, but we must brace ourselves for the worst just in case :)</p>



<a name="180130180"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/180130180" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edwin Cheng <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#180130180">(Nov 07 2019 at 13:14)</a>:</h4>
<p>I just checked, seem like there are only 2 builtin macros which use eagar expansion. So my first MVP will be implement <code>line!</code> macro first. It seem like not depending on anything complicated.</p>



<a name="180130185"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/180130185" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edwin Cheng <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#180130185">(Nov 07 2019 at 13:14)</a>:</h4>
<p>Another question:, I found that for every builtin macro, An attribute <code>rustc_builtin_macro</code> must be used.  <a href="https://github.com/rust-lang/rust/blob/50f8aadd746ebc929a752e5ffb133936ee75c52f/src/libcore/macros.rs#L1121" target="_blank" title="https://github.com/rust-lang/rust/blob/50f8aadd746ebc929a752e5ffb133936ee75c52f/src/libcore/macros.rs#L1121">link</a>. But I don't know it is a good idea depends on it to recognize the input path as bultin-macro because I don't know how stable it is. </p>
<p>On the other hand, it simplifies the whole builtin macro name resolution alot; We could just mark the macro in name resolution phase as builtin, and handle it in <code>ModCollector</code>.</p>



<a name="180130299"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/180130299" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#180130299">(Nov 07 2019 at 13:16)</a>:</h4>
<p><span class="user-mention" data-user-id="216201">@Edwin Cheng</span> that attribute is a relatively new <a href="https://github.com/rust-lang/rust/commit/cbcc7dd182b9bf67d664508b82284c5539ef8819#diff-a5a0682c18717c9e06e867e1cf2abeb8" target="_blank" title="https://github.com/rust-lang/rust/commit/cbcc7dd182b9bf67d664508b82284c5539ef8819#diff-a5a0682c18717c9e06e867e1cf2abeb8">addition</a>, but I think we can rely on it</p>



<a name="180130320"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/180130320" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#180130320">(Nov 07 2019 at 13:16)</a>:</h4>
<p>Even if it breaks later, we can just fix the code</p>



<a name="180629066"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/180629066" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edwin Cheng <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#180629066">(Nov 13 2019 at 14:11)</a>:</h4>
<p>I figure out how to do eager macro expansion in current infrastructure finally and implemented <code>concat!</code>. However I can’t test it in whole def collection phase since there’s no way to expand it before <code>include!</code> is implemented. 🙄</p>



<a name="180629211"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/180629211" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#180629211">(Nov 13 2019 at 14:13)</a>:</h4>
<p>hm..... Should we have dedicated macro expansion tests for built-in macros?</p>



<a name="180637584"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/180637584" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edwin Cheng <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#180637584">(Nov 13 2019 at 15:30)</a>:</h4>
<p>Yes, sure we should. However, the actual problem here is: To test the macro name resolution in <code>items</code> scope, we have to start with a macro which expand to <code>Macro::Items</code>, <code>concat</code> itself only expands to <code>expr</code>. Of course I can write a test for it without triggering eager expansion but it is not ideal.</p>



<a name="180637738"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/180637738" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#180637738">(Nov 13 2019 at 15:32)</a>:</h4>
<p>Hm, and I guess, we need name-resolution to write non-trivial test cases? </p>
<p>Like, it seems like it should be possible to test macro expansion without nameres, in theory, but in practice you need name resolution for interesting test cases</p>



<a name="180795687"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/180795687" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edwin Cheng <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#180795687">(Nov 15 2019 at 01:55)</a>:</h4>
<blockquote>
<p>Like, it seems like it should be possible to test macro expansion without nameres, in theory, but in practice you need name resolution for interesting test cases</p>
</blockquote>
<p>Yes, and FYI :  in <a href="https://github.com/rust-analyzer/rust-analyzer/pull/2244" target="_blank" title="https://github.com/rust-analyzer/rust-analyzer/pull/2244">#2244</a>, I added some <a href="https://github.com/rust-analyzer/rust-analyzer/blob/f3bc12b6fb2ecdd38a3814512d1acb86a3f32c04/crates/ra_hir_expand/src/builtin_macro.rs#L192" target="_blank" title="https://github.com/rust-analyzer/rust-analyzer/blob/f3bc12b6fb2ecdd38a3814512d1acb86a3f32c04/crates/ra_hir_expand/src/builtin_macro.rs#L192">trivial tests</a> without name resolutions.</p>



<a name="180795955"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/180795955" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edwin Cheng <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#180795955">(Nov 15 2019 at 02:01)</a>:</h4>
<p>After that PR, I will work on <code>include!</code>, but I have some questions :</p>



<a name="180795962"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/180795962" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edwin Cheng <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#180795962">(Nov 15 2019 at 02:02)</a>:</h4>
<ol>
<li>If I understand correctly, currently the file loading is "push" model: It insert files at the beginning of project loading. However, how do I handle the following case (which exists in my other project):</li>
</ol>
<div class="codehilite"><pre><span></span><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">font</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Vec</span>::<span class="n">from</span><span class="p">(</span><span class="n">include_bytes</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;DejaVuSans.ttf&quot;</span><span class="p">)</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="o">&amp;</span><span class="p">[</span><span class="kt">u8</span><span class="p">]);</span><span class="w"></span>
</pre></div>


<p>I don't think we push all files in <code>SourceRoot</code>, right?</p>



<a name="180796587"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/180796587" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edwin Cheng <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#180796587">(Nov 15 2019 at 02:17)</a>:</h4>
<ol start="2">
<li>Imagine to support something like this (<a href="https://github.com/intellij-rust/intellij-rust/pull/4542" target="_blank" title="https://github.com/intellij-rust/intellij-rust/pull/4542">https://github.com/intellij-rust/intellij-rust/pull/4542</a>): <br>
The <code>HirFileId</code> of the expanded include! macro is <code>{MacroFile(MacroCallId(lib.rs:include!(concat(..)))}</code> . Note that we don't have the information of <code>hello.rs</code> in the chain of <code>HirFileId</code>. </li>
</ol>
<p>Any idea how to handle it correctly ?</p>



<a name="180805405"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/180805405" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#180805405">(Nov 15 2019 at 06:04)</a>:</h4>
<p>Yeah, the model is push-based. Specifically, rust-analyzer need to know that a file exists before reading it. I've spend about a week trying to transition to a fully-pull based model, but figured out that, ideally, we want a hybrid model.</p>
<p>The <em>set</em> of files is push based, while the contents is pulled. The main reason for this is that, for file watching to be reliable, you need to scan for all files anyway. In particular, if you subscribe to a glob using watchman, it will immediately send all file paths to you as <em>modified</em>.</p>



<a name="180805426"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/180805426" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#180805426">(Nov 15 2019 at 06:05)</a>:</h4>
<p>So, for <code>DejaVuSans.ttf</code>, the user will have to explicitly configure rust-analyzer to care about files with <code>.ttf</code> extension</p>



<a name="180805586"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/180805586" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#180805586">(Nov 15 2019 at 06:09)</a>:</h4>
<ol start="2">
<li>My gut feeling that maybe we <em>shouldn't</em> create <code>{MacroFile(MacroCallId(lib.rs:include!(concat(..)))}</code>? Like, when we made <code>CallID</code> with <code>include!</code>, we already know that it is special. So perhaps we can expand it at that point and use <code>FilleId</code>?</li>
</ol>



<a name="180809647"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/180809647" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edwin Cheng <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#180809647">(Nov 15 2019 at 07:44)</a>:</h4>
<blockquote>
<p>My gut feeling that maybe we shouldn't create {MacroFile(MacroCallId(lib.rs:include!(concat(..)))}? Like, when we made CallID with include!, we already know that it is special. So perhaps we can expand it at that point and use FilleId? </p>
</blockquote>
<p>It is an interesting solution, let me try to implement it first and see if there is any problem. <span aria-label="+1" class="emoji emoji-1f44d" role="img" title="+1">:+1:</span></p>



<a name="180896435"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/180896435" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edwin Cheng <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#180896435">(Nov 16 2019 at 05:02)</a>:</h4>
<p><span class="user-mention" data-user-id="133169">@matklad</span>  I'm trying to implement the new eager expansion method, I have a question: As the new expanded syntax node is not belonged to any HirFileId, This <a href="https://github.com/rust-analyzer/rust-analyzer/blob/ebfba461123928363da55e75195d76314c51fa7e/crates/ra_syntax/src/ptr.rs#L20" target="_blank" title="https://github.com/rust-analyzer/rust-analyzer/blob/ebfba461123928363da55e75195d76314c51fa7e/crates/ra_syntax/src/ptr.rs#L20">line</a> of code basically must fail. How do I solve this ?</p>



<a name="180899204"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/180899204" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edwin Cheng <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#180899204">(Nov 16 2019 at 06:14)</a>:</h4>
<p>(Deleted)</p>



<a name="180904409"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/180904409" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#180904409">(Nov 16 2019 at 09:10)</a>:</h4>
<p><span class="user-mention" data-user-id="216201">@Edwin Cheng</span> I think you souldn't create <code>SyntaxNodePtr</code>s into the eagarly expanded tokens at all</p>



<a name="180904417"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/180904417" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edwin Cheng <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#180904417">(Nov 16 2019 at 09:11)</a>:</h4>
<p>I didn't create it, but it is created by other place I didn't know ...I am tracing it now</p>



<a name="182085886"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/182085886" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edwin Cheng <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#182085886">(Nov 28 2019 at 06:37)</a>:</h4>
<p>@maklad I am thinking how to handle builtin macro and eager macro in a general way, let me show some code first: </p>
<div class="codehilite"><pre><span></span><span class="cp">#[derive(Debug, Clone, PartialEq, Eq, Hash)]</span><span class="w"></span>
<span class="k">pub</span><span class="w"> </span><span class="k">struct</span> <span class="nc">MacroCallLoc</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="p">(</span><span class="k">crate</span><span class="p">)</span><span class="w"> </span><span class="n">def</span>: <span class="nc">MacroDefId</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="p">(</span><span class="k">crate</span><span class="p">)</span><span class="w"> </span><span class="n">ast_id</span>: <span class="nc">AstId</span><span class="o">&lt;</span><span class="n">ast</span>::<span class="n">MacroCall</span><span class="o">&gt;</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="p">(</span><span class="k">crate</span><span class="p">)</span><span class="w"> </span><span class="n">ctx</span>: <span class="nb">Option</span><span class="o">&lt;</span><span class="n">MacroCallSiteCtxId</span><span class="o">&gt;</span><span class="p">,</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="cp">#[derive(Debug, Clone, PartialEq, Eq, Hash)]</span><span class="w"></span>
<span class="k">pub</span><span class="w"> </span><span class="k">enum</span> <span class="nc">MacroCallSiteCtx</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">CurrentFile</span><span class="p">(</span><span class="n">FileId</span><span class="p">),</span><span class="w"></span>
<span class="w">    </span><span class="n">Eager</span><span class="p">(</span><span class="n">Arc</span><span class="o">&lt;</span><span class="n">tt</span>::<span class="n">Subtree</span><span class="o">&gt;</span><span class="p">),</span><span class="w"></span>
<span class="w">    </span><span class="p">...</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">pub</span><span class="w"> </span><span class="k">struct</span> <span class="nc">MacroCallSiteCtxId</span><span class="p">(</span><span class="n">salsa</span>::<span class="n">InternId</span><span class="p">);</span><span class="w"></span>
</pre></div>


<p>My reasoning of this change is, a lot of builtin macros depends on some kind of call site context, such as File Position, Name resolution, Error reporting data etc. If we think of macro expansion as pure token manipulation only, this kind of context should be provided outside of macro_expand. (For example, we COULD compute file position by using <code>MacroCallId::ast_id</code> inside <code>macro_expand</code>) .</p>



<a name="182091015"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/182091015" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#182091015">(Nov 28 2019 at 08:39)</a>:</h4>
<p><span class="user-mention" data-user-id="216201">@Edwin Cheng</span> I would avoid add Context to as a query-parameter: it seems like it can be huge, and would be a bad fit for storage</p>



<a name="182091133"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/182091133" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#182091133">(Nov 28 2019 at 08:41)</a>:</h4>
<p>INstead, I would do something like this:</p>
<div class="codehilite"><pre><span></span>trait AstDatabase {
    #[salsa::inter]
    fn intern_eager_expansion(tt: tt::Subtree) -&gt; EagerExpansionId
}

enum MacroCallId {
    Lazy(our current id here)
    Eager(EagerExpansionId)
}
</pre></div>



<a name="182091211"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/182091211" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#182091211">(Nov 28 2019 at 08:42)</a>:</h4>
<p>That way, when you are processing some code and face an eager macro, you can expand it to token tree using whatever context you have on the stack, and then, to produce appropriate <code>HirFIleId</code> for source maps and such, you can intern the <strong>result</strong> of expanion into an id</p>



<a name="182092024"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/182092024" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edwin Cheng <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#182092024">(Nov 28 2019 at 08:57)</a>:</h4>
<p>Do you think we should move out the builtin macro expansion out of <code>macro_expand</code> such that:</p>
<div class="codehilite"><pre><span></span><span class="c1">// In ra_hir_expand/src/db.rs</span>
<span class="k">impl</span><span class="w"> </span><span class="n">TokenExpander</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">expand</span><span class="p">(</span><span class="w"></span>
<span class="w">        </span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span><span class="w"></span>
<span class="w">        </span><span class="n">db</span>: <span class="kp">&amp;</span><span class="nc">dyn</span><span class="w"> </span><span class="n">AstDatabase</span><span class="p">,</span><span class="w"></span>
<span class="w">        </span><span class="n">id</span>: <span class="nc">MacroCallId</span><span class="p">,</span><span class="w"></span>
<span class="w">        </span><span class="n">tt</span>: <span class="kp">&amp;</span><span class="nc">tt</span>::<span class="n">Subtree</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Result</span><span class="o">&lt;</span><span class="n">tt</span>::<span class="n">Subtree</span><span class="p">,</span><span class="w"> </span><span class="n">mbe</span>::<span class="n">ExpandError</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="k">match</span><span class="w"> </span><span class="n">id</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">            </span><span class="n">Eager</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="n">db</span><span class="p">.</span><span class="n">lookup_eager</span><span class="p">(</span><span class="n">id</span><span class="p">),</span><span class="w">  </span><span class="c1">// return it directly</span>
<span class="w">            </span><span class="n">Lazy</span><span class="p">(</span><span class="n">rules</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="n">rules</span><span class="p">.</span><span class="n">expand</span><span class="p">(</span><span class="n">tt</span><span class="p">),</span><span class="w"></span>
<span class="w">        </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>


<p>And we expand the completed  <em>result</em>  of builtin macros as eager expansion at the call site ? For example, the eager id of <code>concat!("a", "b")</code> is pointing to <code>"ab"</code> instead of<code> ("a","b")</code> directly?</p>



<a name="182092104"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/182092104" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#182092104">(Nov 28 2019 at 08:59)</a>:</h4>
<blockquote>
<p>For example, the eager id of concat!("a", "b") is pointing to "ab" instead of ("a","b") directly?</p>
</blockquote>
<p>I <em>think</em> this should work this way, but I can't explain why this would be better, so it might be actually worse. But I do feel that it's a better approach</p>



<a name="182092377"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/182092377" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#182092377">(Nov 28 2019 at 09:03)</a>:</h4>
<blockquote>
<p>Do you think we should move out the builtin macro expansion out of macro_expand such that:</p>
</blockquote>
<p>Heh, maybe! I <strong>know</strong> that we should provide a nice single entry-point for macro expansion (like we do for <code>Resolver</code>). Currently we do macro expansion in def collector and body::lower, which is not great, and when we support macros in types we will have to expand macros from various places in <code>hir_ty</code>. It's pretty bad that at the moment every macro expansion is basically "do it yourself". There's a nascent expander for expressions, but it is really not well thought out. </p>
<p>We need to add a proper expander, that works in all contexts, deals with hygiene properly, and handles both eager and lazy macros. But I didn't have a chance yet to think how it's API should looks like. It probably should live in the <code>hir_expand</code> crate and get name resolution info via callback.</p>



<a name="182092426"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/182092426" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#182092426">(Nov 28 2019 at 09:04)</a>:</h4>
<p>(oh, and it should handle derives (and maybe even cfg's ?) as well)</p>



<a name="182093094"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/182093094" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edwin Cheng <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#182093094">(Nov 28 2019 at 09:16)</a>:</h4>
<p>Yes, and one of key point I didn't think of before I implement <a href="https://github.com/rust-analyzer/rust-analyzer/blob/4946169a96f3d442f463724af481fdb760381ccb/crates/ra_hir/src/source_binder.rs#L546" target="_blank" title="https://github.com/rust-analyzer/rust-analyzer/blob/4946169a96f3d442f463724af481fdb760381ccb/crates/ra_hir/src/source_binder.rs#L546"><code>to_macro_file_kind</code></a>, we could know the final Node Kind a MacroCallId will expand without parent context. So in theory the whole macro_expand works could be self-contained.</p>



<a name="187010068"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/187010068" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edwin Cheng <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#187010068">(Jan 30 2020 at 17:32)</a>:</h4>
<p>Since <a href="https://github.com/rust-lang/cargo/pull/7622" target="_blank" title="https://github.com/rust-lang/cargo/pull/7622">https://github.com/rust-lang/cargo/pull/7622</a> is landed,  seem like it is possible to implement <code>env!</code> builtin macro now, right ?</p>



<a name="187010107"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/187010107" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#187010107">(Jan 30 2020 at 17:33)</a>:</h4>
<p>right!</p>



<a name="187010109"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/187010109" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edwin Cheng <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#187010109">(Jan 30 2020 at 17:33)</a>:</h4>
<p>And of course another roadblock is eager macro ..</p>



<a name="187010185"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/187010185" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edwin Cheng <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#187010185">(Jan 30 2020 at 17:34)</a>:</h4>
<p>I remember there is a discussion about eager macro and salsa..</p>



<a name="187010227"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/187010227" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#187010227">(Jan 30 2020 at 17:35)</a>:</h4>
<p>which actually didn't happen. Still, It think the idea with just interning eager macro expansions would work</p>



<a name="187010303"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/187010303" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edwin Cheng <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#187010303">(Jan 30 2020 at 17:36)</a>:</h4>
<p>Okay !</p>



<a name="187010306"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/187010306" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#187010306">(Jan 30 2020 at 17:36)</a>:</h4>
<p>We add <code>EagerMaro(id)</code> variant to <code>MacroCallid</code>, and we add <code>#[salsa::inten] fn intern_eager_expansion(result: tt::Subtree) -&gt; EagerMacroId</code></p>



<a name="187010736"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/187010736" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edwin Cheng <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#187010736">(Jan 30 2020 at 17:41)</a>:</h4>
<p>If I remember correctly, Currently we have three places to resolve ast::MacroCall MacroCallId :</p>
<ol>
<li>Item collection phase</li>
<li>Lowering body</li>
<li>SourceAnalyzer</li>
</ol>
<p>Do we want to refactoring it to a single place first ? I did tried that but without success :(</p>



<a name="187010870"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/187010870" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#187010870">(Jan 30 2020 at 17:43)</a>:</h4>
<p>Yeah, creating a single expander would be helpful!</p>



<a name="187011452"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/187011452" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edwin Cheng <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#187011452">(Jan 30 2020 at 17:49)</a>:</h4>
<p>Let me try again, but recently there is some awkward situation in HK (the damn virus) and maybe it would a little bit slower :(</p>



<a name="187011523"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/187011523" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#187011523">(Jan 30 2020 at 17:50)</a>:</h4>
<p><span aria-label="heart" class="emoji emoji-2764" role="img" title="heart">:heart:</span> </p>
<p>Be sure to keep yourself safe!</p>



<a name="187011637"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/187011637" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edwin Cheng <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#187011637">(Jan 30 2020 at 17:50)</a>:</h4>
<p>sure! thanks <span aria-label="heart" class="emoji emoji-2764" role="img" title="heart">:heart:</span> !</p>



<a name="189430188"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Support%20builtin%20macros/near/189430188" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Edwin Cheng <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Support.20builtin.20macros.html#189430188">(Mar 01 2020 at 11:34)</a>:</h4>
<div class="codehilite"><pre><span></span>#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum MacroCallId {
    LazyMacro(LazyMacroId),
    EagerMacro(EagerMacroId),
}
</pre></div>


<p>I am not satisfied the name of <code>LazyMacro</code> ,  Would it be better if I name it to <code>OrdinaryMacro</code> instead ?</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>